package particleField;

import javax.media.opengl.GL;

import SimpleOpenNI.SimpleOpenNI;

import processing.core.PApplet;
import processing.core.PImage;
import processing.core.PVector;
import processing.opengl.PGraphicsOpenGL;

public class ToPoint01 extends PApplet{
	
	ParticleSystem ps;
	int mouseX_old;
	int mouseY_old;
	int width = 1280;
	int height = 960;
	PImage newImg; 
	boolean mod;
//	PGraphicsOpenGL gl;
	
	SimpleOpenNI context;
	float zoomF = 0.5f;
	float rotX = radians(180);
	
	float rotY = radians(0);
	int[] userColors = { color(255, 0, 0), color(0, 255, 0), color(0, 0, 255),
			color(255, 255, 0), color(255, 0, 255), color(0, 255, 255) };
	int[] userCoMColors = { color(255, 100, 100), color(100, 255, 100),
			color(100, 100, 255), color(255, 255, 100), color(255, 100, 255),
			color(100, 255, 255) };
	int[] depthMap;
	PVector[] realWorldOld;
	PVector projectiveOld;
	int[] oldUserMap;

	public void setup() {
		size(width, height, OPENGL);
		context = new SimpleOpenNI(this);
	
		// disable mirror
		context.setMirror(true);

		// enable depthMap generation
		context.enableDepth();

		// enable skeleton generation for all joints
		context.enableUser(SimpleOpenNI.SKEL_PROFILE_ALL);
		
		// enable the scene, to get the floor
		context.enableScene();
		
//		PGraphicsOpenGL gl = (PGraphicsOpenGL) g;
		
		colorMode(RGB, 255, 255, 255, 100);
		ps = new ParticleSystem(1, new PVector(width,height), this);
	//		smooth();
//		hint(ENABLE_OPENGL_4X_SMOOTH);
		mouseX_old = height/2;
		mouseY_old = width/2;
		ps.force_disable_home();
		fill( 15,0);
		stroke(0);
		ellipse(mouseX, mouseY, 15, 15);
		background(0x00FFFFFF);
//		ps.add_magnet(this, new PVector(100, 100), 200, true);
		realWorldOld = context.depthMapRealWorld();
	}

	public void draw() {
		// update the cam
		context.update();
		depthMap = context.depthMap();
		int steps = 15; // to speed up the drawing, draw every third point
		int index;
		PVector realWorldPoint;
		
//		if(frameCount%1000 == 0) background(0x00FFFFFF);
		background(0x00000000);
		
		int userCount = context.getNumberOfUsers();
		int[] userMap = null;
		if (userCount > 0) {
			userMap = context.getUsersPixels(SimpleOpenNI.USERS_ALL);			
		}
		
		stroke(255);
		fill(255);
		for (int y = 0; y < context.depthHeight(); y += steps) {
			for (int x = 0; x < context.depthWidth(); x += steps) {
				index = x + y * context.depthWidth();
				if (depthMap[index] > 0) {
					// get the realworld points
					realWorldPoint = context.depthMapRealWorld()[index];
					PVector projectivePoint = new PVector();
					context.convertRealWorldToProjective(realWorldPoint, projectivePoint);
					// check if there is a user
					if (userMap != null && oldUserMap != null && userMap[index] == 1 && oldUserMap[index] == 0) { // calc the user color
//						System.out.println(userMap[index] + "=?=" + oldUserMap[index]);
						
						ps.addForceDirection( new PVector(projectivePoint.x*2, projectivePoint.y*2) );
						
//						double angle_d = -1;
//						if(index-context.depthWidth() > 0 && userMap[index-context.depthWidth()] == 0){
//							angle_d = 270;
//						}else if(userMap[index+context.depthWidth()] == 0){
//							angle_d = 90;
//						}else if(index-1 > 0 && userMap[index-1] == 0){
//							angle_d = 180;
//						}else if(userMap[index+1] == 0){
//							angle_d = 0;
//						}						
//						if(angle_d != -1) ps.addForceDirection( new PVector(projectivePoint.x*2, projectivePoint.y*2), angle_d );
						rect(projectivePoint.x*2, projectivePoint.y*2, 1, 1);
//							ps.addForceDirection( new PVector(projectivePoint.x*2, projectivePoint.y*2) );

					} 
				}
			}
		}
		
		if (userCount > 0) {
			oldUserMap = userMap.clone();
		}
		
		
//		ps.addForceDirection( new PVector(300, 300) );
		
		if(mousePressed){
			ps.gravity();
		}
		
//		if(mouseX_old != mouseX && mouseY_old != mouseY){
//			int radius = (int) new PVector(mouseX_old, mouseY_old).dist( new PVector(mouseX, mouseY));
//			
//			if(radius < 800){
////				ps.add_magnet(this, new PVector(mouseX, mouseY), 70, true);
//				ps.addForceDirection( new PVector(mouseX, mouseY), new PVector(mouseX_old, mouseY_old) );
////				ps.add_magnet(this, new PVector(mouseX, mouseY), 30, false);
//
//			}
//			
//		}
//		mouseX_old = mouseX;
//		mouseY_old = mouseY;
		realWorldOld = context.depthMapRealWorld();
		if(this.frameCount % 50 == 0) System.out.println(this.frameRate);
		ps.run(this);
		
//		if (mouseButton == LEFT){
//			ps.add_magnet(new PVector(width/2-300, height/2), 100, false);
//		}else if(mouseButton == RIGHT){
//			ps.add_magnet(new PVector(width/2, height/2), 100, true);
//		}

//		ps.add_magnet(this, new PVector(300, 300), 100, false);
//		ps.add_magneticBox(this, 20);
		
		
//		for (int i = 0; i < 1; i++) {	
//			ps.addParticle(mouseX,mouseY);	
//		}
		
		
//		ellipse(50, 50, 50, 50);
//		newImg = fastblur( this.get() );
//		image(newImg, 0, 0);
		
//		filter(BLUR, 1.0F);
		
//		newImg = loadImage("ellipse_blur.png");
//		image(newImg, 30, 30);
		
//		text(frameRate, 10, 10);

	}
	
	void onNewUser(int userId) {
		println("onNewUser - userId: " + userId);
	}

	void onLostUser(int userId) {
		println("onLostUser - userId: " + userId);
	}
	
	PImage fastblur(PImage img) {
		
		for (int x = 1; x < height-1; x++) {
			for (int y = 1; y < width-1; y++) {
				int newVal_g = img.get(x-1, y-1)&0xFF + img.get(x-1, y)&0xFF + img.get(x-1, y+1)&0xFF
						+ img.get(x, y-1)&0xFF + img.get(x, y)&0xFF + img.get(x, y+1)&0xFF
						+ img.get(x+1, y-1)&0xFF + img.get(x+1, y)&0xFF + img.get(x+1, y+1)&0xFF;
				newVal_g = newVal_g/9;
				img.set(x, y, newVal_g);
				
			}			
		}
		return img;
	}

}
